#include "apdu_factory_manager.h"

#include "../../mk_lib/mk_utility.h"

#include <string.h>
#include <memory.h>
#include <stdlib.h>

apdu_factory_manager::apdu_factory_manager( void )
{

}

apdu_factory_manager::~apdu_factory_manager( void )
{

}

apdu * apdu_factory_manager::create_apdu_format( cosDevInfo * devInfo, unsigned char devAuthKey[32], 
												int retryTimes, int leftTimes, int isHighLevel)
{
	apdu * newApdu = new apdu(SC_APDU_CASE_3_EXT, 0xC0, 0x00, isHighLevel,0x00, "Format");

	int pos = 0;
	unsigned char cmd[1024] = {0};
	strcpy((char*)cmd, "mCOSInit");
	pos += 8;

	memcpy(cmd + 8, devInfo, sizeof(cosDevInfo));
	pos += sizeof(cosDevInfo);

	memcpy(cmd + pos, devAuthKey, 32);
	pos += 32;

	cmd[pos++] = (unsigned char)retryTimes;
	cmd[pos++] = (unsigned char)leftTimes;


	newApdu->set_lc_data(cmd, pos);

	return newApdu;

}

apdu * apdu_factory_manager::create_apdu_get_fs_maxcap()
{
	apdu * newApdu = new apdu(SC_APDU_CASE_2_EXT, 0xC0, 0x02, 0x00,0x00, "GetFSMaxCap");
	newApdu->set_le(4);

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_get_hw_sn()
{
	apdu * newApdu = new apdu(SC_APDU_CASE_2_EXT, 0xC0, 0x04, 0x00,0x00, "GetRawHWSN");

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_back_to_bootloader( char * password )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_3_EXT, 0xC0, 0x06, 0x00,0x00, "BackToBootloader");

	unsigned char cmd[64] = {0};
	strcpy((char*)cmd, password);

	newApdu->set_lc_data(cmd, 8);

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_get_dev_status()
{
	apdu * newApdu = new apdu(SC_APDU_CASE_2_EXT, 0xC0, 0x08, 0x00,0x00, "GetDevStatus");

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_read_oeminfo( int offset, int length )
{
	unsigned char cmd[2] = {0};
	memcpy(cmd, &offset, 2);
	
	apdu * newApdu = new apdu(SC_APDU_CASE_2_EXT, 0xC0, 0x0A, cmd[1],cmd[0], "ReadOemInfo");
	newApdu->set_le(length);

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_write_oeminfo( int offset, unsigned char * info, int info_len )
{
	unsigned char cmd[2] = {0};
	memcpy(cmd, &offset, 2);

	apdu * newApdu = new apdu(SC_APDU_CASE_3_EXT, 0xC0, 0x0C, cmd[1],cmd[0], "WriteOemInfo");
	newApdu->set_lc_data(info, info_len);

	return newApdu;
}

apdu * apdu_factory_manager::create_apdu_lock_cos( unsigned char * password, int pwd_len )
{
	apdu * newApdu = new apdu(SC_APDU_CASE_3_EXT, 0xC0, 0x0E, 0, 0, "LockCos");
	newApdu->set_lc_data(password, pwd_len);

	return newApdu;
}

